home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
-
- #include <stream.h>
- #include "tags.h"
- #include "instr.h"
- #include "hash_table.h"
- #include "string_table.h"
- #include "scan.h"
- #include "inst_args.h"
- #include "memory.h"
- #include "basics.h"
- #include "top_level.h"
- #ifdef WITH_GC
- #include "gc.h"
- #endif
-
- #define max(a,b) (((a) > (b)) ? (a) : (b))
-
- /* conventions: */
- /* a HEAP POINTER is stored by casting it to UNSIGNED */
- /* a STACK POINTER register is stored by casting it to UNSIGNED */
- /* a CODE POINTER is stored by casting it to UNSIGNED */
-
- void Init()
- {
- Cell* var = &E[P->arg1];
- *var = make_cell(TAGREF, var);
- }
-
- void init_control_registers()
- {
- P = P0;
- H = H0;
- R = R0;
- TR = TR0;
- B = B0;
- E = E0;
- for (int i = 0; i < NUMBER_OF_REGISTERS; i++)
- X[i] = 0;
-
- #ifdef WITH_GC
-
- /* move the trail stack down for new space and the marking area */
- int size = window_size + window_size /4 + 1;
- if ((TR0 - H0) < 2 * size)
- top_level_error("Too large a window size\n");
- if (window_size/2 < HMAX_SECURITY)
- top_level_error("Too small a window size\n");
- HMAXHARD = E0;
- HMAXSOFT = HMAXHARD - HMAX_SECURITY;
- HMIN = HMAXHARD - window_size;
- TR = TR0 = HMIN - window_size /4 - 2;
- B0[TR_CP_OFFSET] = cell(TR0);
- B0[H_CP_OFFSET] = cell(HMIN);
- MKMIN = (char*) (TR0 + 1);
-
- /* put H in new space and initialize the 2's pointers */
- H = HMIN;
- H2 = H0;
- E2 = E0;
- TR2 = TR0;
-
- GC_COUNTER = 0;
- gc_scanned = 0;
- gc_copy_scanned = 0;
- gc_survivors = 0;
- tr_scanned = 0;
- tr_survivors = 0;
- gc_time = 0;
- #endif
- }
-
- /* compute the top of the env stack */
- /* allocate the first part of an environment: B + E */
- /* and do a BALR (branch and link: see the IBM 360) */
-
- void Call()
- {
- Cell* top_for_E = E + P->arg2;
- Cell* top_for_B = cellp(B[E_CP_OFFSET]);
- Cell* NewE = max(top_for_E, top_for_B) + E_TOP_OFFSET;
- NewE[B_ENV_OFFSET] = cell(B);
- NewE[E_ENV_OFFSET] = cell(E);
- NewE[P_ENV_OFFSET] = cell(P);
- E = NewE;
-
- #ifdef WITH_GC
- if (H >= HMAXSOFT)
- garbage_collector();
- #else
- if (H > TR)
- top_level_error("Heap Overflow");
- #endif
-
- P = instrp(P->arg1);
- }
-
- /* The original value of CP points to an instruction */
- /* that just report success */
- /* this instruction could be any instruction, for example the last one */
- /* it is even possible to make the compiler generate it for us */
- /* the problem with that is that it will generate it for every procedure */
- void Proceed()
- {
- P = instrp(E[P_ENV_OFFSET]);
- E = cellp(E[E_ENV_OFFSET]);
- #ifdef WITH_GC
- if (E < E2)
- E2 = E;
- #endif
- }
-
- void ExecuteProc()
- {
- if (cellp(B[E_CP_OFFSET]) >= E) {
- Cell* NewE = cellp(B[E_CP_OFFSET]) + E_TOP_OFFSET;
- NewE[B_ENV_OFFSET] = cell(B);
- NewE[E_ENV_OFFSET] = E[E_ENV_OFFSET];
- NewE[P_ENV_OFFSET] = E[P_ENV_OFFSET];
- E = NewE;
- }
-
- #ifdef WITH_GC
- if (H >= HMAXSOFT)
- garbage_collector();
- #else
- if (H > TR)
- top_level_error("Heap Overflow");
- #endif
-
- P = instrp(P->arg1);
- }
-
- void ExecuteLabel() {
- P = instrp(P->arg1);
- }
-
- void Cut() {
- B = cellp(E[B_ENV_OFFSET]);
- }
-
- void Escape() {
- (*procp(P->arg1))();
- }
-
- void Try()
- {
- int number_of_registers = P->arg2;
- B -= FIXED_CP_SIZE + number_of_registers;
- B[E_CP_OFFSET] = cell(E);
- B[H_CP_OFFSET] = cell(H);
- B[TR_CP_OFFSET] = cell(TR);
- B[P_CP_OFFSET] = cell(P);
- B[SIZE_CP_OFFSET] = number_of_registers;
- for (int i = 0; i < number_of_registers; i++)
- B[X1_CP_OFFSET + i] = X[i];
- P = instrp(P->arg1);
- }
-
- void Retry() {
- B[P_CP_OFFSET] = cell(P);
- P = instrp(P->arg1);
- }
-
- void Trust() {
- B = cellp(E[B_ENV_OFFSET]);
- P = instrp(P->arg1);
- }
-
- void TryMeElse()
- {
- int number_of_registers = P->arg2;
- B -= FIXED_CP_SIZE + number_of_registers;
- B[E_CP_OFFSET] = cell(E);
- B[H_CP_OFFSET] = cell(H);
- B[TR_CP_OFFSET] = cell(TR);
- B[P_CP_OFFSET] = P->arg1;
- B[SIZE_CP_OFFSET] = number_of_registers;
- for (int i = 0; i < number_of_registers; i++)
- B[X1_CP_OFFSET + i] = X[i];
- }
-
- void RetryMeElse() {
- B[P_CP_OFFSET] = P->arg1;
- }
-
- void TrustMeElse() {
- B = cellp(E[B_ENV_OFFSET]);
- }
-
- void SwitchOnTerm()
- {
- Cell X0 = deref(X[0]);
- switch(get_tag(X0)) {
- case TAGCONST:
- P = instrp(P->arg1);
- break;
- case TAGLIST:
- P = instrp(P->arg2);
- break;
- case TAGSTRUCT:
- P = instrp(P->arg3);
- break;
- case TAGREF:
- break;
- }
- }
-
- HashTable* table_of_tables;
- void init_run_time_tables()
- {
- table_of_tables = instr_args[ARG_TABLE]->TableOfTables;
- }
-
- void SwitchOnConstant()
- {
- HashTable* table = (HashTable*) table_of_tables->get(P->arg1);
- P = instrp(table->get(deref(X[0])));
- if (table->status == HASH_MISS)
- P = FP0;
- }
-
- void SwitchOnStructure()
- {
- HashTable* table = (HashTable*) table_of_tables->get(P->arg1);
- P = instrp(table->get(*addr(deref(X[0]))));
- if (table->status == HASH_MISS)
- P = FP0;
- }
-
-